using System;
using System.Collections.Generic;
using System.Text;

using Weazel.Microblaze.Simulator.Engine;

namespace Weazel.Microblaze.Simulator.Components.Microblaze.Instructions
{
    /// <summary>
    /// Load word immediate
    /// </summary>
    public class Lwi : MemoryAccessInstruction
    {

        public override int CycleCount
        {
            get { return 1; }
        }

        public Lwi()
            : base("lwi")
        {
        }

        /// <summary>
        /// Loads a word (32 bits) from the word aligned memory location that 
        /// results from adding the contents of register rA and the value IMM, 
        /// sign-extended to 32 bits. The data is placed in register rD.
        /// </summary>    
        public override void Execute(MicroblazeComponent MicroblazeComponent)
        {
            // calculate address
            uint imm = GetImmediateValue(MicroblazeComponent);
            uint ra = MicroblazeComponent.ReadRegister(SourceRegisterA);

            uint address = ra + imm;

          //  Console.WriteLine("reading address: 0x{0:X}", address);

            // clear two lowest bits
            uint maskedAddress = address & 0xFFFFFFFC;

            ReadWordTransaction transaction = new ReadWordTransaction(MicroblazeComponent, maskedAddress);
            MicroblazeComponent.BeginDataTransaction(transaction);

            while (transaction.Status != Transaction.TransactionStatus.Complete)
                MicroblazeComponent.WaitOneCycle();

            /*
            // read memory ..
            uint memory;
            MemoryAccessStatus status = MicroblazeComponent.DataMemorySpace.ReadWord(maskedAddress, out memory);

            if (status == MemoryAccessStatus.Ok)
            {
                // write destination register
                MicroblazeComponent.WriteRegister(DestinationRegister, memory, Address);
            } 
             * */

            MicroblazeComponent.WriteRegister(DestinationRegister, transaction.Value, address);
        }

        public override string ToString()
        {
            return string.Format("lwi r{0}, r{1}, {2}",
              DestinationRegister,
              SourceRegisterA,
              ImmediateValue
            );
        }
    }
}
